﻿using System;
using System.Collections.Generic;
using System.Text;

namespace CpuSimulator.Instructions
{
    /// <summary>
    ///SW(Save Word) 将rs1中的值加上立即数作为地址，把rs2中的数据写入该地址
    /// _________________________________________________________________________________________________________________________________________________
    /// |___________立即数____________ |________rs2,5位______|_________rs1,5位______|_Func3______|_________立即数_____|_____OPCODE 7位____________|
    /// | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
    /// |               imm[11:5]                |               rs2             |       rs1                      |    010          |        imm[4:0]           |            0100011                     |
    /// </summary>
    public class SW : Instruction
    {
        public override void Execute(Cpu cpuinfo)
        {
            int address = cpuinfo.Registers[this.Rs1].Value + this.Immediate;
            Device device = new Device(0);
            int deviceStart = 0;
            foreach (var item in cpuinfo.AddressMap)
            {
                if (address >= item.Key.start && address < item.Key.end)
                {
                    device = item.Value;
                    deviceStart = address - item.Key.start;
                    break;
                }
            }
            if (device != null)
            {
                var bs = BitConverter.GetBytes(cpuinfo.Registers[this.Rs2].Value);
                device[deviceStart] = bs[0];
                cpuinfo.InvodeMemoryChange(address, device[deviceStart].ToString("X2"));
                device[deviceStart+1] = bs[1];
                cpuinfo.InvodeMemoryChange(address+1, device[deviceStart+1].ToString("X2"));
                device[deviceStart + 2] = bs[2];
                cpuinfo.InvodeMemoryChange(address+2, device[deviceStart+2].ToString("X2"));
                device[deviceStart + 3] = bs[3];
                cpuinfo.InvodeMemoryChange(address+3, device[deviceStart+3].ToString("X2"));
            }
        }
    }
}
